using System.Collections.Generic;
using NUnit.Framework;
using ValidationFramework;

namespace ExampleLibraryCSharp.FieldValidationManagerExamples
{
	public class CustomClassExample
	{
		#region Example

		public class Person
		{

			private readonly MemberValidationManager fieldValidationManager;
			[RequiredIntRule]
			public int age;


			public Person()
			{
				fieldValidationManager = ValidationManagerFactory.GetFieldValidationManager(this);
			}


			/// <summary>
			/// Gets <see cref="IList{T}"/> containing all <see cref="ValidationError"/> for <see cref="Rule"/>s that have failed validation.
			/// </summary>
			public virtual IList<ValidationError> ValidatorResultsInError
			{
				get
				{
					return fieldValidationManager.ValidatorResultsInError;
				}
			}


			/// <summary>
			/// Gets a <see see="ICollection"/> of <see langword="string"/>s that contain all 
			/// the <see cref="ValidationError.ErrorMessage"/>s for all the 
			/// <see cref="ValidationError"/>s in <see cref="ValidatorResultsInError"/>.
			/// </summary>
			public virtual IList<string> ErrorMessages
			{
				get
				{
					return ResultFormatter.GetErrorMessages(fieldValidationManager.ValidatorResultsInError);
				}
			}



			/// <summary>
			/// Gets a <see lanword="bool"/> indicating if the current state is valid.
			/// </summary>
			public bool Validate()
			{
				//Base behavior is to perform validations and return boolean value.
				//Sub-class can override this if, for example, they are validating on the fly.
				fieldValidationManager.ValidateAll();
				return fieldValidationManager.IsValid;
			}
		}

		[TestFixture]
		public class ExampleUsage
		{
			[Test]
			public void RunIsValid()
			{
				var person = new Person();

				// Initially not valid
				Assert.IsFalse(person.Validate());

				// Set Age
				person.age = 10;

				// It is now valid
				Assert.IsTrue(person.Validate());
			}



			[Test]
			public void RunValidatorResultsInError()
			{
				var person = new Person();
				Assert.IsFalse(person.Validate());
				// Initially there will be 1 item in ValidatorResultsInError.
				Assert.AreEqual(1, person.ValidatorResultsInError.Count);

				// Set Age
				person.age = 10;

				// Since Validate has not been called the count will not have changed
				Assert.AreEqual(1, person.ValidatorResultsInError.Count);

				Assert.IsTrue(person.Validate());
				// Since Validate has now been called the count will have changed
				Assert.AreEqual(0, person.ValidatorResultsInError.Count);
			}


		}
		#endregion
	}
}